<?php
class MY_Module extends MY_Model {

	var $_layout;
	public static $_widgets = null;
	public static $_modules = null;
	var $_view_dir = 'modules/';
	var $table_modules = "modules";
	var $table_modules_position = "modules_position";
	var $primaryKey = "MOD_ID";

	public function __construct() {
		parent::__construct();
		$this->_view_dir = $this->template->prefix_frontend.'modules/';
	}

	public function init($config) {
		return $config;
	}

	public function set_layout($layout) {
		$this->_layout = $layout;
		$this->loads();
	}
	
	public function loads($layout_id = 0, $position = '')
	{
		$this->load->model('modules_m', 'modules');
		$this->load->model('modules_position_m','mposition');
		
		if (self::$_widgets == null || !isset(self::$_widgets[$layout_id])|| !isset(self::$_widgets[$layout_id][$position])) {
			if($layout_id >0)
			$this->mposition->where('layout_id', $layout_id);
	
			$this->mposition->where('mpos_position', $position);
			$this->mposition->order_by('mpos_order');
			$widgets = $this->mposition->get_many_by();
			$module_id = array();
			if($widgets)
			{
				foreach($widgets as $widget)
				{
					if (!isset(self::$_widgets[$widget->layout_id])) {
						self::$_widgets[$widget->layout_id] = array();
					}
					if (!isset(self::$_widgets[$widget->layout_id][$widget->mpos_position])) {
						self::$_widgets[$widget->layout_id][$widget->mpos_position] = array();
					}
					self::$_widgets[$widget->layout_id][$widget->mpos_position][] = $widget;
					$module_id[$widget->module_id] = $widget->module_id;
				}
			}
			$module_id = @array_keys($module_id);
			$module_id_self = @array_keys(self::$_modules);
			if ($module_id_self == null || @array_diff($module_id, $module_id_self)) {
				if ($module_id) {
					$modules = $this->modules
							->where_in('module_id', $module_id)->get_many_by();
					if ($modules)
						foreach ($modules as $module) {
							self::$_modules[$module->module_id] = $module;
						}
				}
			}
			return @self::$_widgets[$layout_id][$position];
		}
		return FALSE;
	}
	

	public function _active() {
		
		//do something here;
		$this->active();
	}

	public function _deactive() {
		
		//do something here;
		$this->deactive();
	}
	public function active() {
		
	}

	public function deactive() {
		
	}

	public function admin($config) {
		
	}

	public function run($config) {
		
	}
	
	public function module_update($data) {
		return $data;
	}
	

	public function view($view_name, $data = array(), $return = FALSE) {
		if($return) 
			return $this->load->view($this->_view_dir . strtolower(get_class($this)) . '/' . $view_name, $data, $return);
		
		$this->load->view($this->_view_dir . strtolower(get_class($this)) . '/' . $view_name, $data, $return);
	}

	public function is_active_module($name) {
		$module = $this->mmodules->get($name, 'MOD_NAME');
		if ($module)
		return true;
		return false;
	}
}

class Modules {
	public static $_view_dir = 'modules/';
	private static $_CI = NULL;
	private static $module_instance = NULL;
	
	public function __construct() {
		self::$_CI = & get_instance();
	}
	
	public static function get_dir()
	{
		return Modules::$_view_dir;
	}
	
	
	public static function load_widgets($layout_id = '', $position= '')  {
		if (self::$module_instance == NULL) 
			self::$module_instance = new MY_Module();
		$widgets = self::$module_instance->loads($layout_id,$position);
		if ($widgets) foreach ($widgets as $widget) {
			$mod_name = MY_Module::$_modules[$widget->module_id]->module_name;
			self::$module_instance->load->model('modules/'.$mod_name);
			$config = json_decode($widget->mpos_config, true);
			$config ['widget_title']  = $widget->mpos_title;
			$config ['widget_id']  = $widget->mpos_id;
			$config ['widget_layout']  = $widget->layout_id;
			$config ['widget_position']  = $widget->mpos_position;
			$config = self::$module_instance->$mod_name->init($config);
			self::$module_instance->$mod_name->run($config);
		}
	}
	
	
	/*
		using: echo Modules::run('controller/method', $param, $...); 
	*/
	public static function run($module = '')
	{
		if($module == '')
		{
			$bt = debug_backtrace();
			$caller = array_shift($bt);
			log_message('error', "Module not name in line   {$caller['line']} file {$caller['file']}");
			return '';
		}
		$method = 'run';
		
		
		if(($pos = strrpos($module, '/')) != FALSE) {
			$method = substr($module, $pos + 1);		
			$module = substr($module, 0, $pos);
		}
		if($class = $module && function_exists($module)) {
			if (method_exists(self::$_CI->{$class}, $method))	{
				ob_start();
				$args = func_get_args();
				self::$_CI->load->module($class);
				$output = call_user_func_array(array(self::$_CI->{$class},$method), array_slice($args, 1));
				$buffer = ob_get_clean();
				 log_message('debug', 'Module '.$module.' Initialized');
				return ($output !== NULL) ? $output : $buffer;
			}
		}
		log_message('error', "Module controller failed to run: {$module}/{$method}");
	}
	
}